#include <stdio.h>
#include <stdlib.h>
#include <error.h>
#include <errno.h>
#include <assert.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <math.h>
#include <sys/wait.h>
#include <sys/select.h>
#include <sys/time.h>
#include <getopt.h>

#include "utility.h"
#include "rsa.h"
#include "format.h"
#include "cli_socket_handle.h"
#include "server_detect.h"
#include "user.h"
#include "event2/dns.h"


int main(int argc, char *argv[])
{
	printClientMenu();
    int err = 0;
    int32_t socket_type = 0;    //SOCK_STREAM 或 SOCK_DGRAM
    char user_name[NAME_PASSWD_SESSION_LEN];
    char user_passwd[NAME_PASSWD_SESSION_LEN];
    struct sockaddr_in serv_addr[2];
    bzero(user_name,NAME_PASSWD_SESSION_LEN);
    bzero(user_passwd,NAME_PASSWD_SESSION_LEN);
    if (argc < 2)
    {
        printf("%s -t/u [-n name] [-p passwd]\n", argv[0]);
        exit(-1);
    }

    /* 1.获取服务器IP与端口 */
    get_server_by_name(SERVER_DOMAIN_NAME, EVDNS_TYPE_A, serv_addr);

    /* 2.获取运行参数 */
    int ch;
    while ((ch = getopt(argc, argv, "tun:p:")) != -1)
    {
        switch (ch)
        {
        case 't':
            socket_type = SOCK_STREAM;
            break;
        case 'u':
            socket_type = SOCK_DGRAM;
            break;
        case 'n':
            bzero(user_name, NAME_PASSWD_SESSION_LEN);
            memcpy(user_name, optarg, MIN(NAME_PASSWD_SESSION_LEN-1, strlen(optarg) + 1));
            break;
        case 'p':
            bzero(user_passwd, NAME_PASSWD_SESSION_LEN);
            memcpy(user_passwd, optarg, MIN(NAME_PASSWD_SESSION_LEN-1, strlen(optarg) + 1));
            break;
        default:
            printf("other option :%c\n", ch);
        }
    }
    if (socket_type == 0)
    {
        printf("%s -t/u 选择连接方式[t:TCP,u:UDP]\n", argv[0]);
        exit(-1);
    }


    /* 3.与服务器建立连接 */
    int sockfd = connect_file_trans_serv(&serv_addr[socket_type - 1], socket_type);
    assert(sockfd != -1);

    /* 4.登录 */
    err = client_login(sockfd, socket_type, &serv_addr[1], user_name, user_passwd);
    if (err != 0)
    {
        fprintf(stderr, "client_login() failed\n");
        close(sockfd);
        exit(-1);
    }
    
    /* 5.初始化工作路径与工作目录 */
    err = client_file_path_init(user_name);
    assert(err == 0);

    /* 6.循环监听套接字与标准输入 */
    printf("input command>");
    fflush(stdout);
    fd_set rfds;
    while (1)
    {
        FD_ZERO(&rfds);
        FD_SET(sockfd, &rfds);
        FD_SET(0, &rfds); //监听标准输入
        err = select(sockfd + 1, &rfds, NULL, NULL, NULL);
        if (err == -1)
        {
            perror("select()");
            exit(-1);
        }
        else if (err)
        {
            if (FD_ISSET(sockfd, &rfds))
            {
                socket_read(sockfd, socket_type, &serv_addr[1]);
            }
            else if (FD_ISSET(0, &rfds))
            {
                stdin_read(sockfd, socket_type, &serv_addr[1]);
            }
            else
            {
                printf("unexpected FD_ISSET() retval\n");
            }
        }
        else
        {
            printf("unexpected select() return %d\n", err);
            exit(-1);
        }
    }
    return 0;
}

